Choosing Between Find and Single in Entity Framework
Last month, I mentioned to a colleague that one should not blindly use the First() method when working with Entity Framework. Even when retrieving data by primary key, where First() and Single() yield the same result, and First() might be slightly more performant (due to the difference between TOP 1 and TOP 2), there is still a semantic distinction between retrieving the "first" record (First()) and retrieving a "single" record (Single()).
At the time, a colleague asked me about the differences regarding the Find() method. Since I don't use this method very often, my answer was incomplete. I have now reorganized the relevant content.
Semantic Differences Between Find and Get
In most cases, the usage scenarios for Find and Get methods differ. When using methods starting with Find, if the corresponding data is not found, it usually returns a default value; whereas methods starting with Get will, in most cases, throw an exception.
To be honest, this definition is not absolute, and I sometimes confuse the differences between the two myself.
Explanation of the Find() Method
First, let's look at the definition of the Find() method:
public virtual TEntity? Find (params object?[]? keyValues);The parameter here is an object[], so if you are not familiar with the database table, you cannot determine if the input parameter type is correct at compile time. This is especially true when dealing with composite primary keys; if you are unclear about the order defined by ColumnAttribute or the Fluent API, you may not know how to pass the parameters correctly.
Find() has the following characteristics:
- It first searches for entities already present in the local cache. The local cache includes:
- Data loaded via
Load(). - Entities queried using methods like
ToList()orSingle(). - Entities added to the
DbSetviaAdd().
- Data loaded via
- If the corresponding entity is not found in the local cache, it will send a query to the database.
- If you use
AsNoTracking()when querying data with methods likeToList()orSingle(), the result will not be stored in the local cache. Furthermore,Find()cannot be used on aDbSetafterAsNoTracking()has been applied. - The
Find()method can only query a single entity and does not support eager loading of related data likeInclude().
Conclusion
The specific method to use should depend on your requirements. However, I prefer using methods like Single() and SingleOrDefault() because they have clearer semantics and do not have the various limitations associated with Find().
Change Log
- 2024-07-16 Initial version created.
